#ifndef __LYRICFILE_H__
#define __LYRICFILE_H__

namespace SPlayer
{
    namespace Music
    {
        ref class LyricLocateInfo;
        public ref class LyricInfoEventDispatcher
        {
        public:
            System::Action ^onLyricChanged;
        };
        public ref class LyricLocateInfo : System::IComparable < LyricLocateInfo^ >
        {
        public:
            virtual int CompareTo(LyricLocateInfo ^other)
                = System::IComparable<LyricLocateInfo^>::CompareTo
            {
                auto big = this->index - other->index;
                if (big != 0)
                    return big;
                return this->leftPlayOffset - other->leftPlayOffset;
            }
            unsigned index = 0; /*the zero based index in lines*/
            unsigned leftPlayOffset = 0;/* = playOffset requisted - playOffset_of_index*/
            double progress = 0;/* = leftPlayOffset / (playOffset_of_next_index - playOffset_of_index)*/
        };
        public ref class LyricLineInfo : System::IComparable < LyricLineInfo^ >
        {
        public:
            virtual int CompareTo(LyricLineInfo ^other)
                = System::IComparable<LyricLineInfo^>::CompareTo
            {
                return this->playOffset - other->playOffset;
            }
            unsigned playOffset;
            System::String ^text;
        };
        public ref class LyricInfo
        {
        public:
            LyricInfo ^Clone();
        public:
            LyricLocateInfo ^locate(unsigned playOffset);
            unsigned locateToPlayOffset(int index, double progress);
            System::String ^toString();
        public:
            void addTimeLine(unsigned playOffset, System::String ^text);
            void deleteTimeLine(unsigned lineIndex);
            void setText(unsigned lineIndex, System::String ^text);
            void ajustOffset(unsigned millsecond);
        private:
            void _addTimeLine_nosort(unsigned playOffset, System::String ^text);
            void _addLabel(System::String ^name, System::String ^text);
            void _applyInternalOffset();
            void _sortTimeLine();
            void _refillTimeIndexs();


        public:
            static LyricInfo ^loadFromString(System::String ^str, unsigned length);
            static LyricInfo ^load(System::String ^filename, unsigned length);
            static LyricInfo ^load(System::IO::TextReader ^reader, unsigned length);
            static LyricInfo ^createNew();
        public:
            LyricInfoEventDispatcher ^eventDispatcher = gcnew LyricInfoEventDispatcher;
            System::Collections::Generic::List<LyricLineInfo ^> ^lines = gcnew System::Collections::Generic::List < LyricLineInfo ^ > ;
            int offset = 0;
            System::Collections::Generic::Dictionary<System::String ^, System::String ^> ^labels = gcnew System::Collections::Generic::Dictionary < System::String ^, System::String ^ > ;
        private:
            System::Collections::Generic::SortedList<unsigned /*millsecond*/, unsigned /*index*/> ^_timeIndex = nullptr;
            unsigned finalPlayOffset = 0;
        };
    }
}

#endif // __LYRICFILE_H__